package com.itservice.supporter_navi;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.google.android.gcm.GCMRegistrar;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.GroundOverlay;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.itservice.supporter_navi.MarathonDataBase.MarathonDataBase;
import com.itservice.supporter_navi.MarathonDataBase.libs.Convention;
import com.itservice.supporter_navi.MarathonDataBase.libs.DBUtilities;
import com.itservice.supporter_navi.utilities.CommonMethod;
import com.itservice.supporter_navi.utilities.CommonUtilities;
import com.itservice.supporter_navi.utilities.GCMSendMsg;

public class MainActivity extends android.support.v4.app.FragmentActivity implements OnClickListener,LocationListener,OnCameraChangeListener{
	//====================================================================
	// UI関係変数宣言
	//====================================================================
	private Button Regist_Button;					// 登録画面遷移ボタン用
	private Button Friend_List_Button;				// フレンドリスト画面遷移ボタン用
	private Button Runner_Mode_Button;				// ランナーモード切替ボタン用

	private MarathonDataBase marathonDB; 			// データベースクラス

	// カメラの初期座標位置を設定（後に決める必要あり）
	static final float INITIAL_ZOOM_LEVEL = 16;
    static final double INITIAL_LATITUDE = 34.6923215;
    static final double INITIAL_LONGITUDE = 135.531994;

	private GoogleMap map;
	private LocationManager locationManager;
	private ListView list;
	private ArrayAdapter<String> adapter;
	List<RunnerData> datalist = new ArrayList<RunnerData>();

	//====================================================================
	// メンバ変数宣言
	//====================================================================
	private String getID="";					// 送信相手のID保管用
	private Context context = this;				// コンテキスト引き渡し用
	private boolean thread_endflg=false;		// GPS取得要求スレッドの終了フラグ
	private double my_latitude = 0;				// 緯度
	private double my_longitude = 0;			// 経度
	private int change_no =0;					// 変更があった番号
	private int section =0;						// レーン番号
	private boolean list_flg=false;				// メニュー動的表示フラグ
	private boolean menu_flg=true;				// メニュー静的表示フラグ
	Looper looper;
	Handler mhandler;
	GroundOverlayOptions[] options_overlay = new GroundOverlayOptions[CommonUtilities.MAX_REGISTER];
	//IDBG 0621 拡縮変更処理
	float now_zoom=0.0f;
	// 拡縮フラグ
	boolean zoom_flg=false;
	// メニューボタン内リスト番号（1：ランナー対応表 表示切替）
	private static final int MENU_ID_MENU1 = (Menu.FIRST + 1);
	private static final int MENU_ID_MENU2 = (Menu.FIRST + 2);

	private boolean map_disp_flg=false;

	// オーバーレイ表示フラグ
	private boolean[] ol_flg = {false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false,
								false,false,false,false,false,false,false,false,false,false};

	// リスト表示フラグ(10人分)
	private boolean[] list_disp_flg = {false,false,false,false,false,false,false,false,false,false};

	GroundOverlay[] overlay = new GroundOverlay[CommonUtilities.MAX_REGISTER];


	//======================================================================================
	// メイン処理（UI関係インスタンス取得、メールからの起動時処理）
	//======================================================================================
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i(CommonUtilities.LOG_TAG,"OnCreate:実行");
		setContentView(R.layout.activity_main);

		// DBインスタンス取得
        marathonDB = MarathonDataBase.getInstance();
		marathonDB.setContext(this);

		//=======================================================
		// デバイスとマニュフェストがGCM使用可能状態かを判定する
		//=======================================================
		try{
			// デバイスチェック
			GCMRegistrar.checkDevice(this);
			// マニュフェストチェック
			GCMRegistrar.checkManifest(this);
		}
		catch(Exception e ){
			Log.d(CommonUtilities.LOG_TAG, "Exception :" + e);
		}



		//=======================================================
		// GPSがONかOFFかを判定してOFFなら設定画面に遷移する処理
		//=======================================================
		boolean GPS_State = CommonMethod.CheckGPS(this);
		if(GPS_State==false){
			// GPSサービスがOFFになっているので、メッセージ表示
			AlertDialog.Builder gsDialog = new AlertDialog.Builder(context);
			gsDialog.setTitle("GPS OFF");
			gsDialog.setMessage("GPSがオフになっています。\nGPSをオンにして下さい");
			gsDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					// 端末のGPS設定画面へ誘導する
					Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
					intent.addCategory(Intent.CATEGORY_DEFAULT);
					startActivity(intent);
				}
			});
			gsDialog.setNegativeButton("スキップ", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {

				}
			}).create().show();
		}


		// インターネットがONかOFFかを判定してOFFなら設定画面に遷移する処理
		//boolean NET_State = CommonMethod.CheckNET(this);


		//=====================================================
		// UI関係設定
		//=====================================================

		// 登録画面表示ボタン
		Regist_Button = (Button)findViewById(R.id.Regist_Button);
		Regist_Button.setOnClickListener(this);

		// フレンドリスト表示ボタン
		Friend_List_Button = (Button)findViewById(R.id.Friend_List_Button);
		Friend_List_Button.setOnClickListener(this);

		// ランナーモード切替ボタン
		Runner_Mode_Button = (Button)findViewById(R.id.Runner_Mode_Button);
		Runner_Mode_Button.setOnClickListener(this);

		// ランナー対応表用リスト取得
		list = (ListView)findViewById(R.id.runner_list);
		// 初期表示状態は非表示
		list.setVisibility(View.INVISIBLE);


		//=============================================================
		// ランナーモード中からの起動時処理
		//=============================================================
		boolean Runner_Mode_Flg = marathonDB.getBoolean(DBUtilities.RUNNER_MODE,false);
		if(Runner_Mode_Flg==true){
			marathonDB.setBoolean(DBUtilities.RUNNER_MODE,false);
			stopService(new Intent(context, GPSManagerService.class));
		}


		//=============================================================
		// マップの設定（マップ表示位置、コース表示）
		//=============================================================
		locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
		// 自身のGPS取得開始
        if (locationManager != null) {
			locationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER,
					0,
					0,
					this);
		}

        // マップ表示メソッド呼び出し
		MAPDisplay();

		// ランナー位置表示メソッド呼び出し
		RunnerView();

        //==============================================
		// メールから起動された場合
		//==============================================
		Intent intent = getIntent();
		Log.i(CommonUtilities.LOG_TAG, "Intent :" + intent );
		boolean start_type = intent.getBooleanExtra(CommonUtilities.START_FLG,false);
		if(start_type==false){
		    String action = intent.getAction();
			Log.d(CommonUtilities.LOG_TAG, "Mail Send!!:" + action);
		    if(Intent.ACTION_VIEW.equals(action)){
				Log.d(CommonUtilities.LOG_TAG, Intent.ACTION_VIEW);
		    	Uri uri = intent.getData();
		    	if (uri!=null) {
					Log.d(CommonUtilities.LOG_TAG,"uri" + uri.toString());
		    		String url="";
		    		url = uri.toString();
		    		String[] array_url = url.split("/");
		    		Log.i(CommonUtilities.LOG_TAG, array_url[3]);
		    		Log.i(CommonUtilities.LOG_TAG, array_url[4]);
		    		Intent i = new Intent(context,FriendListActivity.class);
		    		i.putExtra(CommonUtilities.INTENT_STATUS, CommonUtilities.INTENT_STATUS_MAIL);
		    		i.putExtra(CommonUtilities.INTENT_MAIL_FRIEND_ID, array_url[3]);
		    		i.putExtra(CommonUtilities.INTENT_MAIL_FRIEND_KEY, array_url[4]);
					startActivity(i);
		    	}
		    }
		}else{
			//==============================================
			// Notificationから起動された場合
			//==============================================
			Log.i(CommonUtilities.LOG_TAG, "start_type:" + start_type);
			String N_friend_ID = intent.getStringExtra(CommonUtilities.NOTIFICATION_FRIEND_ID);
			Intent i = new Intent(context,FriendListActivity.class);
			i.putExtra(CommonUtilities.INTENT_STATUS, CommonUtilities.INTENT_STATUS_NOTIFICATION);
			i.putExtra(CommonUtilities.INTENT_FRIEND_ID,N_friend_ID);
			startActivity(i);
		}

		// 登録されているフレンド人数を取得
		int friend_num = marathonDB.getInteger(DBUtilities.FRIEND_NUM, 0);

		// 登録人数が0ではない時登録者全員の位置情報と更新フラグを初期化する
		if(friend_num!=0){
    		// 初期化処理
    		for(int i=1;i<=friend_num;i++){
    			marathonDB.removeText(DBUtilities.FRIEND_CHAGE_FLG + i);
    			marathonDB.removeText(DBUtilities.FRIEND_LATITUDE + i);
    			marathonDB.removeText(DBUtilities.FRIEND_LONGITUDE + i);
    		}
		}


	}



	//======================================================================================
	// アクティビティがフォアグラウンドに復帰した時の処理
	//======================================================================================
	@Override
	public void onResume(){
		super.onResume();
		Log.i(CommonUtilities.LOG_TAG,"OnResume:復帰");
		//=============================================================
		// ランナーモード中からの起動時処理
		//=============================================================
		// 現在のモードを取得
		boolean Runner_Mode_Flg = marathonDB.getBoolean(DBUtilities.RUNNER_MODE,false);
		// ランナーモードであるかを判定
		if(Runner_Mode_Flg==true){
			// ランナーモードである場合、モードを応援者に変更する
			marathonDB.setBoolean(DBUtilities.RUNNER_MODE,false);
			// GPS取得サービスを止める
			stopService(new Intent(context, GPSManagerService.class));
			// ノーティフィケーションを操作する為のマネージャーを取得

		}
		NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		// ランナーモードのノーティフィケーションを消去
		notificationManager.cancelAll();
		// ランナー表示スレッドの復帰
		thread_endflg=false;

        // GPS取得要求送信処理
        GPSThread();

        // 自身のGPS取得開始
        if (locationManager != null) {
			locationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER,
					0,
					0,
					this);
		}
	}

	//======================================================================================
	// アプリが起動中にIntentを受け取った場合（メールから起動、ノーティフィケーション起動等）
	//======================================================================================
	@Override
	public void onNewIntent(Intent intent) {
		Log.i(CommonUtilities.LOG_TAG, "onNewIntent :" + intent );
		if(intent != null){
			boolean start_type = intent.getBooleanExtra(CommonUtilities.START_FLG,false);
			if(start_type==false){
			    String action = intent.getAction();
				Log.d(CommonUtilities.LOG_TAG, "Mail Send!!:" + action);
			    if(Intent.ACTION_VIEW.equals(action)){
					Log.d(CommonUtilities.LOG_TAG, Intent.ACTION_VIEW);
			    	Uri uri = intent.getData();
			    	if (uri!=null) {
						Log.d(CommonUtilities.LOG_TAG,"uri" + uri.toString());
			    		String url="";
			    		url = uri.toString();
			    		String[] array_url = url.split("/");
			    		Log.i(CommonUtilities.LOG_TAG, array_url[3]);
			    		Log.i(CommonUtilities.LOG_TAG, array_url[4]);
			    		Intent i = new Intent(context,FriendListActivity.class);
			    		i.putExtra(CommonUtilities.INTENT_STATUS, CommonUtilities.INTENT_STATUS_MAIL);
			    		i.putExtra(CommonUtilities.INTENT_MAIL_FRIEND_ID, array_url[3]);
			    		i.putExtra(CommonUtilities.INTENT_MAIL_FRIEND_KEY, array_url[4]);
						startActivity(i);
			    	}
			    }
			}else{
				//==============================================
				// Notificationから起動された場合
				//==============================================
				Log.i(CommonUtilities.LOG_TAG, "start_type:" + start_type);
				String N_friend_ID = intent.getStringExtra(CommonUtilities.NOTIFICATION_FRIEND_ID);
				Intent i = new Intent(context,FriendListActivity.class);
				i.putExtra(CommonUtilities.INTENT_STATUS, CommonUtilities.INTENT_STATUS_NOTIFICATION);
				i.putExtra(CommonUtilities.INTENT_FRIEND_ID,N_friend_ID);
				startActivity(i);
			}
		}
	}


	//======================================================================================
	// アクティビティがバックグラウンドに遷移した時の処理
	//======================================================================================
	@Override
	public void onPause(){
		super.onPause();
		// 位置情報取得処理が動いているか
		if (locationManager != null) {
			// 位置情報取得処理を止める
			locationManager.removeUpdates(this);
		}
		thread_endflg = true; //GPS取得要求スレッドを停止
	}

	//======================================================================================
	// アプリ終了時の処理
	//======================================================================================
	@Override
	public void onDestroy(){
		super.onDestroy();
		// GPS取得サービスを終了させる
		stopService(new Intent(context, GPSManagerService.class));
		NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		// 表示されているノーティフィケーションを全消去
		notificationManager.cancelAll();
	}

	//======================================================================================
	// ランナー対応表に追加する処理
	//======================================================================================
	protected void setAdapters(){
		// リストビューにカスタムしたリストアダプタを設定する
		list.setAdapter(new CustomAdapter(context, datalist));
	}

	//======================================================================================
	// ボタンがタップされた時の処理
	//======================================================================================
	@Override
	public void onClick(View v) {
		//===================================
		// 登録画面呼び出し処理
		//===================================
		if (v == Regist_Button){
			boolean NET_State = CommonMethod.CheckNET(context);
			if(NET_State==true){
				Intent i = new Intent(context,UserRegistActivity.class);
				startActivity(i);
			}else{
				// ダイアログ表示
				// GPSサービスがOFFになっているので、メッセージ表示
				AlertDialog.Builder gsDialog = new AlertDialog.Builder(this);
				gsDialog.setTitle("Network OFF");
				gsDialog.setMessage("ネットワークが使用出来ない為\nユーザ登録操作は行えません。\n機内モードがONに設定されているか\n圏外の可能性があります。");
				gsDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {

					}
				}).create().show();

				Log.i(CommonUtilities.LOG_TAG,"ネットワークに問題があります。（機内モードの可能性もあります）");
			}
		}

		//====================================
		// フレンドリスト画面呼び出し処理
		//====================================
		if (v == Friend_List_Button){

			// インターネットがONかOFFかを判定してOFFなら設定画面に遷移する処理
			boolean NET_State = CommonMethod.CheckNET(context);
			if(NET_State==true){
				Intent i = new Intent(context,FriendListActivity.class);
				i.putExtra("Mail_Start_Flg", false);
				startActivity(i);
			}else{
				// ダイアログ表示
				// GPSサービスがOFFになっているので、メッセージ表示
				AlertDialog.Builder gsDialog = new AlertDialog.Builder(this);
				gsDialog.setTitle("Network OFF");
				gsDialog.setMessage("ネットワークが使用出来ない為\nフレンドリスト操作は行えません。\n機内モードがONに設定されているか\n圏外の可能性があります。");
				gsDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {

					}
				}).create().show();
				Log.i(CommonUtilities.LOG_TAG,"ネットワークに問題があります。（機内モードの可能性もあります）");
			}
		}

		//==================================
		// ランナーモード切替処理
		//==================================
		if (v == Runner_Mode_Button){
			// インターネットがONかOFFかを判定してOFFなら設定画面に遷移する処理
			boolean NET_State = CommonMethod.CheckNET(context);
			if(NET_State==true){
				// GPSがONかOFFかを判定してOFFなら設定画面に遷移する処理
				boolean GPS_State = CommonMethod.CheckGPS(this);
				if(GPS_State==false){
					// GPSサービスがOFFになっているので、メッセージ表示
					AlertDialog.Builder gsDialog = new AlertDialog.Builder(context);
					gsDialog.setTitle("GPS OFF");
					gsDialog.setMessage("GPSがオフになっています。\nGPSをオンにしてから\n再度ランナーモードボタンを押してください。");
					gsDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							// 端末のGSP設定画面へ誘導する
							Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
							intent.addCategory(Intent.CATEGORY_DEFAULT);
							startActivity(intent);
						}
					});
					gsDialog.setNegativeButton("スキップ", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {

						}
					}).create().show();
				}else{
					//=========================================================
					// ランナーモード処理
					//=========================================================
					AlertDialog.Builder RunnerModeDialog = new AlertDialog.Builder(context);
					RunnerModeDialog.setTitle("スタート地点確認");
					RunnerModeDialog.setMessage("ランナーモードをONにする際は必ずスタート地点で行ってください。\nランナーモードに切り替えますか？");
					RunnerModeDialog.setPositiveButton("OK",new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// 自身をフォアグラウンドからバッククラウンドへ移行させる
							startService(new Intent(context, GPSManagerService.class));
							Intent intent = new Intent(Intent.ACTION_MAIN);
							intent.addCategory(Intent.CATEGORY_HOME);
							startActivity(intent);
							// ランナーモード変更処理
							// GPS取得サービス起動（ランナーモード解除時にサービスをストップさせる）
							marathonDB.setBoolean(DBUtilities.FRIEND_GOAL, false);
							marathonDB.setBoolean(DBUtilities.RUNNER_MODE,true); // ランナーモードフラグをランナーモード中に変更：true
							generateNotificationRunner(context,"ランナーモード中です。");
						}
					});
					RunnerModeDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// Noの場合は何もしない。
						}
					}).create().show();
				}
			}else{
				// ダイアログ表示
				// GPSサービスがOFFになっているので、メッセージ表示
				AlertDialog.Builder gsDialog = new AlertDialog.Builder(this);
				gsDialog.setTitle("Network OFF");
				gsDialog.setMessage("ネットワークが使用出来ない為\nランナーモードは使用できません。\n機内モードがONに設定されているか\n圏外の可能性があります。");
				gsDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {

					}
				}).create().show();

				Log.i(CommonUtilities.LOG_TAG,"ネットワークに問題があります。（機内モードの可能性もあります）");
			}
		}
	}


	//======================================================================================
	// ランナーモード中のノーティフィケーション
	//======================================================================================
    @SuppressLint("NewApi")
	private static void generateNotificationRunner(Context context, String message) {
    	Intent notificationIntent = new Intent(context, MainActivity.class);
    	PendingIntent pendingIntent =
    			PendingIntent.getActivity(context, 0, notificationIntent, 0);

    	//Notification.Builder builder = new Notification.Builder(context);
    	Builder builder = new NotificationCompat.Builder(context);

    	builder.setTicker("ランナーモード中");
    	builder.setContentTitle("マラソン応援アプリ：ランナーモード");
       	builder.setContentText(message);
       	builder.setContentInfo("info");
       	builder.setWhen(System.currentTimeMillis());
       	builder.setContentIntent(pendingIntent);
       	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
       	Notification notification = builder.build();

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        notification.flags = Notification.FLAG_ONGOING_EVENT;
        notificationManager.notify(CommonUtilities.NOTIFICATION_ID_RANNER, notification);
    }

	//======================================================================================
	// MAP表示処理
    //======================================================================================
    private void MAPDisplay(){
    	// Fragmentの取得
		FragmentManager manager = getSupportFragmentManager();
		SupportMapFragment frag = (SupportMapFragment) manager.findFragmentById(R.id.map);
		// GoogleMapの取得
    	map = frag.getMap();

    	// マップがnullの時は処理しない
    	if(map!=null){
    		Log.i(CommonUtilities.LOG_TAG,"マップ取得完了");
			//初期位置
			//規定値にセットする
	        LatLng target = new LatLng(INITIAL_LATITUDE,INITIAL_LONGITUDE);
	        //ズームレベル
	        float zoom = INITIAL_ZOOM_LEVEL;
	        //チルトアングル
	        float tilt = 0.0f; // 0.0 - 90.0
	        //向き
	        float bearing = 0.0f;
	        if(map==null){
	        	Log.i(CommonUtilities.LOG_TAG,"NULLだぼけ");
	        }
	        //CameraUpdate
	        map.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(target, zoom, tilt, bearing)));

			// 大会コースデータリストを取得
	        ArrayList<Convention> conventionList = marathonDB.GetConventionList();

	        map.setOnCameraChangeListener(this);

	        // 大会コースを設定
	        // ダミーデータ、今回は先頭(大阪マラソン)を設定する。
	        Boolean ret = marathonDB.SetConvention(conventionList.get(CommonUtilities.COURSE_OBP_TEST).No);
	        Log.v("MarathonApplication", "[" + ret + "]ConventionNo :" + conventionList.get(CommonUtilities.COURSE_OBP_TEST).No);
	        if(ret == true)
	        {
	    		// 現在位置&コース描画
	    		// ライン
	    		PolylineOptions options = new PolylineOptions();
	    		options.color(Color.RED);
	    		options.width(10);
	    		options.geodesic(true); // 測地線で表示

	    		double line_latitude; // 緯度
	    		double line_longitude; // 経度

	    		for(int i = 0; i <marathonDB.GetCourseMaxPointNum(); i++)
	        	{
	    			line_latitude  = marathonDB.GetCourseDataLatitude(i);
	    			line_longitude = marathonDB.GetCourseDataLangitude(i);
	    			// スタート地点の取得
	    			if(i == 0){
	    				marathonDB.setText(DBUtilities.START_LATITUDE, Double.toString(line_latitude));
	    				marathonDB.setText(DBUtilities.START_LONGITUDE, Double.toString(line_longitude));
	    			}

	    	        Log.v("MarathonApplication", "line_latitude[" + line_latitude + "]line_longitude[" + line_longitude + "]");
	    			if((line_latitude == 0) && (line_longitude == 0))
	    			{
	    				break;
	    			}
	        		options.add(new LatLng(line_latitude, line_longitude));
	        	}
	    		//IDBG 0621 階層順設定
	    		options.zIndex(0);
	    		map.addPolyline(options);
	        }
	        if(ret == true)
	        {
	    		// 距離表示情報描画
	    		// マーカー
	        	MarkerOptions options = new MarkerOptions();

	    		double marker_latitude; // 緯度
	    		double marker_longitude; // 経度


	    		for(int i = 0; i <marathonDB.GetDistanceMaxPointNum(); i++)
	        	{
	    			marker_latitude  = marathonDB.GetDistanceDataLatitude(i);
	    			marker_longitude = marathonDB.GetDistanceDataLangitude(i);
	    			options.title(marathonDB.GetDistanceDataTitle(i));
	        	    options.snippet(marathonDB.GetCourseDataComment(i));

	    	        Log.v("MarathonApplication", "line_latitude[" + marker_latitude + "]line_longitude[" + marker_longitude + "]");
	    			if((marker_latitude == 0) && (marker_longitude == 0))
	    			{
	    				break;
	    			}
	            	LatLng position = new LatLng(marker_latitude, marker_longitude);
	            	options.position(position);
	            	map.addMarker(options);
	        	}
	        }
	        map_disp_flg=true;
    	}else{
    		Log.i(CommonUtilities.LOG_TAG,"Mapの取得に失敗しました。");
    		map_disp_flg=false;
    	}
    }



    //======================================================================================
  	// ランナー表示処理
  	//======================================================================================
    private void RunnerView(){
    	new Thread(new Runnable() {
            @Override
            public void run() {
            	boolean end_flg=false;
            	while(end_flg==false){
            		if(map_disp_flg==true){
	            		// 登録しているフレンド数を取得
	            		int reg_cnt = marathonDB.getInteger(DBUtilities.FRIEND_NUM, 0);
	            		// 登録人数分更新が行われているか判定する
	            		for(int i = 1;i<=reg_cnt;i++){
	            			// フレンド毎に更新が行われているかを取得する
	            			boolean gps_flg = marathonDB.getBoolean(DBUtilities.FRIEND_CHAGE_FLG + i, false);
	            			// フレンドリストにてチェックが外された事による非表示変更を行うかを取得
	            			boolean disp_end = marathonDB.getBoolean(DBUtilities.FRIEND_DISPLAY_END + i, false);
	            			// 非表示処理ではない時の処理
	            			if(disp_end == false){
	            				// 変更が加わっている場合の処理
		            			if(gps_flg == true){
		            				// ランナーの位置情報を取得
		            				String lati  = marathonDB.getText(DBUtilities.FRIEND_LATITUDE + i, "0.0");
		            				String longi = marathonDB.getText(DBUtilities.FRIEND_LONGITUDE + i, "0.0");
		            				// ランナーの走行レーンを取得
		            				section = marathonDB.getInteger(DBUtilities.FRIEND_SECTION + i, -1);
		            				// ランナーの名前を取得
		            				String name = marathonDB.getText(DBUtilities.FRIEND_NAME+i, "noName");
		            				if((!(lati.equals("0.0"))) && (!(longi.equals("0.0"))) && section != -1){
			            				//=================================================
			            				// 左上に表示するランナー対応表を出す処理
			            				//=================================================
			            				// 静的表示フラグが表示になっている場合
			            				if(menu_flg == false){
			            					// 動的フラグが非表示の場合
				            				if(list_flg==false){
				            					// UIへ表示切替を行い、動的表示フラグを変更
				            					looper = Looper.getMainLooper();
				        			        	mhandler = new Handler(looper);
				        			        	mhandler.post(new Runnable(){
				        			        		@Override
				        			        		public void run(){
				        			        			// UI部品への操作
				        			        			// ランナー対応表を表示する
				        			        			list.setVisibility(View.VISIBLE);
				        			        		}
				        			        	});
				        			        	// 動的表示フラグを表示に変更
				            					list_flg = true;
				            				}
			            				}else{// 静的表示フラグが非表示になっている場合
			            					// 動的表示フラグが非表示の時
			            					if(list_flg==false){
			            						// 動的表示フラグのみ表示に変更
			            						list_flg = true;
			            					}
			            				}

			            				//========================================================
			            				// マップにカーソルを表示する処理
			            				//========================================================
			            				double run_lati = Double.parseDouble(lati);
			        					double run_longi = Double.parseDouble(longi);

			        					// 緯度、軽度をひとくくりで設定
			        					LatLng position = new LatLng(run_lati, run_longi);

			        					// フレンドリストで割りあてられた使用色を取得
			        					int my_color = marathonDB.getInteger(DBUtilities.FRIEND_COLOR + i, -1);

			        					// カーソルの使用色を初期化
			        					BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_red);

			        					// 使用色が割りあてられている場合
			        					if(my_color != -1){
			        						// 使用色毎に処理を行う
				        					switch(my_color){
				        						// 赤色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_RED:
					        						// カーソル画像（赤）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_red);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_RED]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_red, name));
					        							// ランナー対応表での赤色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_RED] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 青色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_BLUE:
					        						// カーソル画像（青）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_blue);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_BLUE]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_blue, name));
					        							// ランナー対応表での青色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_BLUE] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 緑色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_GREEN:
					        						// カーソル画像（緑）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_green);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_GREEN]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_green, name));
					        							// ランナー対応表での緑色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_GREEN] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 黄色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_YELLOW:
					        						// カーソル画像（黄）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_yellow);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_YELLOW]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_yellow, name));
					        							// ランナー対応表での黄色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_YELLOW] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 橙色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_ORANGE:
					        						// カーソル画像（橙）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_orange);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_ORANGE]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_orange, name));
					        							// ランナー対応表での橙色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_ORANGE] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 水色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_SKY:
					        						// カーソル画像（水）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_sky);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_SKY]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_sky, name));
					        							// ランナー対応表での水色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_SKY] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 灰色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_GRAY:
					        						// カーソル画像（灰）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_gray);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_GRAY]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_gray, name));
					        							// ランナー対応表での灰色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_GRAY] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 紫色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_PURPLE:
					        						// カーソル画像（紫）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_purple);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_PURPLE]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_purple, name));
					        							// ランナー対応表での紫色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_PURPLE] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 黄緑色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_YELLOWGREEN:
					        						// カーソル画像（黄緑）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_yellowgreen);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_YELLOWGREEN]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_yellowgreen, name));
					        							// ランナー対応表での黄緑色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_YELLOWGREEN] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					// 桃色が設定されている場合
					        					case CommonUtilities.CURSOR_COLOR_PINK:
					        						// カーソル画像（桃）を設定
					        						descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_pink);
					        						// ランナー対応表表示用配列に追加
					        						if(list_disp_flg[CommonUtilities.CURSOR_COLOR_PINK]==false){
					        							// 配列に名前と使っている画像情報を設定
					        							datalist.add(new RunnerData(R.drawable.runner_icon_pink, name));
					        							// ランナー対応表での桃色使用状況を使用中に変更
					        							list_disp_flg[CommonUtilities.CURSOR_COLOR_PINK] = true;
					        						}
					        						looper = Looper.getMainLooper();
					        			        	mhandler = new Handler(looper);
					        			        	mhandler.post(new Runnable() {
					        			        		@Override
					        			        		public void run() {
					        			        			// UI部品への操作
					        			        			// ランナー対応表を更新
							        						setAdapters();
					        			        		}
					        			        	});
					        						break;
					        					default:
					        						break;
				        					}


				        					GroundOverlayOptions options_ol = new GroundOverlayOptions();
				        					options_overlay[i] = options_ol;

				        					// 貼り付ける設定
				        			    	options_overlay[i].image(descriptor);
				        			    	//IDBG 0621 アンカー値変更
				        			    	options_overlay[i].anchor(0.5f,0.5f);
				        			    	//IDBG 0621 階層順設定
				        			    	options_overlay[i].zIndex(1);

				        			    	//IDBG 0621 ズーム率取得
				        			    	looper = Looper.getMainLooper();
				        		        	mhandler = new Handler(looper);
				        		        	mhandler.post(new Runnable() {
				        		        		@Override
				        		        		public void run() {
				        		        			now_zoom = map.getCameraPosition().zoom;
				        		        			//Log.v("activate","zoom:" + zoom);
				        		        		}
				        		        	});

				        		        	//IDBG 0621 拡縮調整
				        		        	//===========================================================**
				        			    	// ズーム処理
				        			    	//===========================================================**
				        		        	Log.i(CommonUtilities.LOG_TAG, "now_zoom:" + now_zoom);
				        		        	if(now_zoom==0.0){
				        		        		now_zoom = INITIAL_ZOOM_LEVEL;
				        		        	}

				        			    	float zoom_pos = CursorZoom(now_zoom);

				        			    	options_overlay[i].position(position, zoom_pos);

				        			    	Log.i(CommonUtilities.LOG_TAG, "倍率:" + zoom_pos);

				        					change_no = i;
				        					if(ol_flg[i] == false){
				        						looper = Looper.getMainLooper();
				        			        	mhandler = new Handler(looper);
				        			        	mhandler.post(new Runnable() {
				        			        		@Override
				        			        		public void run() {
				        			        			// UI部品への操作
				        			        			overlay[change_no] = map.addGroundOverlay(options_overlay[change_no]);
				        			        			overlay[change_no].setBearing(marathonDB.GetCourseDataAngle(section));

				        			        		}
				        			        	});

				        					}
				        					// マップに貼り付け・アルファを設定
				        					if(ol_flg[i] == true){
				        						looper = Looper.getMainLooper();
				        			        	mhandler = new Handler(looper);
				        			        	mhandler.post(new Runnable() {
				        			        		@Override
				        			        		public void run() {
				        								overlay[change_no].remove();
				        								overlay[change_no] = map.addGroundOverlay(options_overlay[change_no]);
				        								overlay[change_no].setBearing(marathonDB.GetCourseDataAngle(section));
				        			        		}
				        			        	});
				        					}
				        					ol_flg[i] = true;
				        					// 更新フラグを更新完了状態へ変更
				        					marathonDB.setBoolean(DBUtilities.FRIEND_CHAGE_FLG + i ,false);
			        					}
			            			}
		            			}
	            			}else{
	            				//======================================================
	            				// フレンドリストにてチェックが外された時の処理
	            				//======================================================
	            				if(ol_flg[i] == true){
	        						looper = Looper.getMainLooper();
	        			        	mhandler = new Handler(looper);
	        			        	mhandler.post(new Runnable() {
	        			        		@Override
	        			        		public void run() {
	        			        			// スレッド内のUI処理
	        			        			// 出していたカーソルを消去
	        								overlay[change_no].remove();
	        			        		}
	        			        	});
	        					}
	            				// カーソル表示中フラグを非表示に
	            				ol_flg[i] = false;
	            				// 更新フラグを更新無へ
	        					marathonDB.setBoolean(DBUtilities.FRIEND_CHAGE_FLG + i ,false);
	        					// 表示終了フラグを終了完了へ
	        					marathonDB.setBoolean(DBUtilities.FRIEND_DISPLAY_END + i, false);
	        					// ランナー対応表から除外するために使っていた色を取得
	        					int usedcolor = marathonDB.getInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
	        					// カーソル色割り当てが行われていない場合は行わない
	        					if(usedcolor != -1){
	        						// 現在登録されているリストの全体数を取得（最大10）
	        						int list_length = datalist.size();
		        					// 使っていた色から消すべき対象を判断し、リストから除外する
	        						//（名前でも判定できるが、重複の危険がある為色を使用する）
		        					switch(usedcolor){
		        						//使用していた色が赤色の場合
		        						case CommonUtilities.CURSOR_COLOR_RED:
		        							// リスト中で赤色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが赤であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_red){
		        									// 登録画像が赤だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での赤色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_RED] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返しを終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が青色の場合
		        						case CommonUtilities.CURSOR_COLOR_BLUE:
		        							// リスト中で青色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが青であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_blue){
		        									// 登録画像が青だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での青色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_BLUE] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返しを終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が緑色の場合
		        						case CommonUtilities.CURSOR_COLOR_GREEN:
		        							// リスト中で緑色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが緑色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_green){
		        									// 登録画像が緑だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での緑色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_GREEN] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が黄色の場合
		        						case CommonUtilities.CURSOR_COLOR_YELLOW:
		        							// リスト中で黄色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが黄色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_yellow){
		        									// 登録画像が黄色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での黄色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_YELLOW] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が橙色の場合
		        						case CommonUtilities.CURSOR_COLOR_ORANGE:
		        							// リスト中で橙色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが橙色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_orange){
		        									// 登録画像が橙色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での橙色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_ORANGE] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が水色の場合
		        						case CommonUtilities.CURSOR_COLOR_SKY:
		        							// リスト中で水色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが水色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_sky){
		        									// 登録画像が水色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での水色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_SKY] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が灰色の場合
		        						case CommonUtilities.CURSOR_COLOR_GRAY:
		        							// リスト中で灰色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが灰色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_gray){
		        									// 登録画像が灰色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での灰色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_GRAY] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が紫色の場合
		        						case CommonUtilities.CURSOR_COLOR_PURPLE:
		        							// リスト中で紫色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが紫色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_purple){
		        									// 登録画像が紫色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での紫色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_PURPLE] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が黄緑色の場合
		        						case CommonUtilities.CURSOR_COLOR_YELLOWGREEN:
		        							// リスト中で黄緑色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが黄緑色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_yellowgreen){
		        									// 登録画像が黄緑色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での紫色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_YELLOWGREEN] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						// 使用していた色が桃色の場合
		        						case CommonUtilities.CURSOR_COLOR_PINK:
		        							// リスト中で桃色の画像が設定されている項目を検索
		        							for(int j = 0; j<list_length;j++){
		        								// リスト毎の情報を取得
		        								RunnerData r_data = datalist.get(j);
		        								// 登録されている画像IDが桃色であるかを判定
		        								if(r_data.resourceId == R.drawable.runner_icon_pink){
		        									// 登録画像が桃色だった場合、その項目をリストから除外
		        									datalist.remove(j);
		        									// ランナー対応表での桃色使用状況を未使用に変更
		        									list_disp_flg[CommonUtilities.CURSOR_COLOR_PINK] = false;
		        									// 使用していた色を未使用状態に変更
		        									marathonDB.setInteger(DBUtilities.FRIEND_COLOR_OLD + i, -1);
		        									// 使用色が見つかり次第繰り返し終了
		        									break;
		        								}
		        							}
		        							break;
		        						default:
		        							break;
		        					}
	        					}

	        					//===================================================================
	        					// 表示されているカーソルが存在しない場合、ランナー対応表を非表示へ
	        					//===================================================================
	        					// リスト表示フラグが10色全て未使用になっているかを判定
	        					for(int list_no = 0; list_no < CommonUtilities.CURSOR_COLOR_TYPE;list_no++){
	        						// ランナー対応表に表示しているかを取得
	        						boolean disp_check = list_disp_flg[list_no];
	        						// 表示しているかを判定
	        						if(disp_check==true){
	        							// 一つでも表示されていればループアウト
	        							break;
	        						}else{
	        							looper = Looper.getMainLooper();
		        			        	mhandler = new Handler(looper);
		        			        	mhandler.post(new Runnable() {
		        			        		@Override
		        			        		public void run() {
		        			        			// UI部品への操作
		        			        			// 全て表示されていなければリストを非表示に変更
		        			        			list.setVisibility(View.INVISIBLE);
		        			        		}
		        			        	});
		        			        	// ランナー対応表表示状態を非表示に変更
		            					list_flg = false;
	        						}
	        					}
	            			}
	            		}
            		}
    				// ディレイ処理
    				try {
            			// 無限ループを0.5秒止める(これがないと延々この処理だけが動いてしまい、送信処理をうけつけなくなる、むしろ落ちる)
    					Thread.sleep(1000);
    				} catch(InterruptedException except) {
    					except.printStackTrace();
    				}
            	}
            }
         }).start();
    }

    //======================================================================================
    // ズーム時のカーソル表示倍率を計算します
   	//======================================================================================
    private float CursorZoom(float zoom){
    	float ans = 0.0f;
    	if(zoom > 16){
    		ans = 10 * (21 - zoom);
    	}else if(zoom > 14){
    		ans = 10 * ((21 - zoom) * 2);
    	}else if(zoom > 13){
    		ans = 10 * ((21 - zoom) * 4);
    	}else if(zoom > 12){
    		ans = 10 * ((21 - zoom) * 8);
    	}else if(zoom > 11){
    		ans = 10 * ((21 - zoom) * 16);
    	}else if(zoom > 10){
    		ans = 10 * ((21 - zoom) * 32);
    	}else{
    		ans = 10 * ((21 - zoom) * 64);
    	}

    	Log.i(CommonUtilities.LOG_TAG, "倍率:" + ans);

    	return ans;
    }


    //======================================================================================
    // メニューを作成します。メニューボタンタップ時に一度だけ実行されます。
    //======================================================================================
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
 		// メニューアイテムを追加します
 		menu.add(Menu.NONE, MENU_ID_MENU1, Menu.NONE, "ランナー対応表 表示切替");
 		menu.add(Menu.NONE, MENU_ID_MENU2, Menu.NONE, "Legal Notices(免責事項)");
 		return super.onCreateOptionsMenu(menu);
 	}

	//=====================================================================================
	// メニュー選択後の処理
 	//======================================================================================
 	@Override
 	public boolean onOptionsItemSelected(MenuItem item) {
 		boolean ret = true;
 		switch (item.getItemId()) {
 		case MENU_ID_MENU1:
 			ret = true;
 			if(menu_flg==true && list_flg == true){
 				// 表示状態へ変更
 				list.setVisibility(View.VISIBLE);
 				menu_flg=false;
 			}else if (menu_flg == false){
 				// 非表示状態へ変更
 				list.setVisibility(View.INVISIBLE);
 				menu_flg=true;
 			}
 			break;
 		case MENU_ID_MENU2:
 			// Google Maps を使用する上での免責事項
 			String Legal_Notices = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(context);
 			AlertDialog.Builder LegalNoticesDialog = new AlertDialog.Builder(context);
 			LegalNoticesDialog.setTitle("LegalNotices(免責事項)");
 			LegalNoticesDialog.setMessage(Legal_Notices);
 			LegalNoticesDialog.setPositiveButton("OK",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					// 動作としては何もしない、テキストを表示するだけ
				}
			}).create().show();
 			break;
 		default:
			ret = super.onOptionsItemSelected(item);
			break;
		}
		return ret;
 	}


    //======================================================================================
  	// GPS取得要求送信処理
  	//======================================================================================
    private void GPSThread(){
    	new Thread(new Runnable() {
	        @Override
	        public void run() {
	        	thread_endflg = false;
	        	while(thread_endflg==false){
	        		int friend_num = marathonDB.getInteger(DBUtilities.FRIEND_NUM, 0);
	        		if(friend_num!=0){
		        		getID = marathonDB.getText(DBUtilities.USER_ID,"NoID"); 				// 自身のGCMIDを取得
		        		if(getID.equals("NoID")){
		        			// no content
		        		}else{
			        		String[] Array_Send_ID = new String[friend_num];
			        		boolean send_flg = false;
			        		for(int i=1;i<=friend_num;i++){
			        			int friend_state = marathonDB.getInteger(DBUtilities.FRIEND_STATUS+i, 1);
			        			if(friend_state==DBUtilities.FRIEND_STATUS_RUNNER){
			        				Array_Send_ID[i-1] = marathonDB.getText(DBUtilities.FRIEND_ID+i, "");
			        				send_flg = true;
			        			}
			        		}
			        		if(send_flg == true){
				        		Log.i(CommonUtilities.LOG_TAG,"3 送信");
				        		SendAsyncTask task = new SendAsyncTask(Array_Send_ID,CommonUtilities.M_TYPE_GET_GPS + "," + getID + ",");
				        		task.execute();
				        		send_flg = false;
			        		}
		        		}
	        		}
	        		try {
	        			// 取得要求送信サイクルを設定（現在3秒：3000ms）
						Thread.sleep(CommonUtilities.NEXT_SEND_TIME);
					} catch(InterruptedException e) {
						e.printStackTrace();
					}
				}
	        }
        }).start();
    }



    // 位置情報が更新されると、onLocationChanged()が呼び出される。
 	// 引数として渡されたLocationを参照することで位置情報の詳細を取得できます。
 	@Override
 	public void onLocationChanged(Location myLocate) {
 		// 緯度経度の取得
 		if(null != myLocate){
 			// 緯度の取得
 			my_latitude = (double) (myLocate.getLatitude());
 			// 経度の取得
 			my_longitude = (double) (myLocate.getLongitude());

 			// 現在位置更新
 			/* 自機位置更新版*/
 			MyLocationSource source = new MyLocationSource();
 			map.setLocationSource(source);
 			map.setMyLocationEnabled(true);
 		}
 	}

 	//現在位置を好きな緯度・経度に設定する
 	private class MyLocationSource implements LocationSource {
 	    @Override
 	    public void activate(OnLocationChangedListener listener) {
 	        // 好きな緯度・経度を設定した Location を作成
 	        Location location = new Location("MyLocation");

 			// 現在位置描画
 			location.setLatitude(my_latitude);
 			location.setLongitude(my_longitude);
 			location.setAccuracy(100); // 精度
 			// Location に設定
 	        listener.onLocationChanged(location);
 	    }

 	    // 処理を止めるときに使う
 	    @Override
 	    public void deactivate(){
 	    }
 	}

 	// 位置情報取得タイミング別処理
 	@Override
 	public void onProviderDisabled(String arg0) {


 	}

 	// 位置情報取得タイミング別処理
 	@Override
 	public void onProviderEnabled(String arg0) {


 	}

 	// 位置情報取得タイミング別処理
 	@Override
 	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {

 	}

	//======================================================================================
	// 送信処理へ送信内容を受渡し
	//======================================================================================
	public class SendAsyncTask extends AsyncTask<String, String, Long> {
		private String[] mRegIds;	// 送信先ID
		private String mMsg;		// 送信メッセージ

		// コンストラクタ
	    public SendAsyncTask(String[] regId , String msg) {
	        this.mRegIds = regId;
	        this.mMsg = msg;
	    }

	    /**
	     * バックグランドで行う処理
	     */
	    @Override
	    protected Long doInBackground(String... params) {
	    	// 送信用メソッドに送信内容を渡す
	        GCMSendMsg.SendMsg(mRegIds,mMsg);
	        return null;
	    }
	}


	/** * アダプタに設定するデータ */
	//======================================================================================
	// ランナー対応表に表示する際に用いるDataタイプクラス
	//======================================================================================
	class RunnerData {
		//画像のリソースID
		int resourceId;
		// 文字列
		String text;

		// 画像IDと名前を設定
		public RunnerData(int resourceId, String text) {
			this.resourceId = resourceId;
			this.text = text;
		}
	}



	//======================================================================================
	// リストに設定するアダプターを自身で用意したDataタイプクラスを継承して作成
	//======================================================================================
	public class CustomAdapter extends ArrayAdapter<RunnerData> {
	     LayoutInflater mInflater;

		 public CustomAdapter(Context cont, List<RunnerData> objects) {
		     // 親のコンストラクタを呼び出す
		     // 2番目の引数はレイアウトのリソースIDだがgetViewで指定するのでここでは0を設定
		     super(cont, 0, objects);
		     // インフレーターを取得する
		     this.mInflater = (LayoutInflater) cont.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		 }

		 @Override
		 public View getView(int position, View convertView, ViewGroup parent) {
		     // ホルダークラスを定義する
		     // ホルダークラスを使うことで再表示時にレイアウト内のビュー検索が無くなり高速化される
		     ViewHolder holder;
		     // ビューを設定する
		     if (convertView == null) {
		         // はじめて呼ばれた時はビューはnullが設定されている
		         // ビューに定義したレイアウトをインフレートする
		         convertView = this.mInflater.inflate(R.layout.runnerlist, parent,false);
		         // ホルダークラスを生成する
		         holder = new ViewHolder();
		         // ホルダークラスにレイアウト内のビューを設定する
		         holder.textView = (TextView) convertView.findViewById(R.id.cell_text);
		         holder.imageView = (ImageView) convertView.findViewById(R.id.cell_image);
		         // タグにホルダークラスを設定する
		         convertView.setTag(holder);
		     } else {
		         // 2回目以降はビューが設定されている
		         // タグからホルダークラスを取得する
		         holder = (ViewHolder) convertView.getTag();
		     }
		     // 指定された位置のアイテムを取得する
		     RunnerData data = getItem(position);
		     // ホルダークラスのビューの値を設定する
		     // convertViewに設定されている内容とgetItem(position)の内容が同じではないので再設定が必要
		     holder.imageView.setImageResource(data.resourceId);
		     holder.textView.setText(data.text);
		     // 表示するビューを返す
		     return convertView;
	    }


	    /**   ホルダクラス     */
	    class ViewHolder {
	        /** イメージビュー */
	        ImageView imageView;
	        /** テキストビュー */
	        TextView textView;
	    }
	}


	//======================================================================================
	// 地図内で動作を行った際の処理（カーソル拡大に使用）
	//======================================================================================
	@Override
	public void onCameraChange(CameraPosition pos){
		if(map_disp_flg==true){
			int reg_cnt = marathonDB.getInteger(DBUtilities.FRIEND_NUM, 0);
			Log.i(CommonUtilities.LOG_TAG, "ID数:" + reg_cnt);
			//===============================================================
			// 拡縮が行われた時の処理
			//===============================================================
			for(int i=1;i<=reg_cnt;i++){
				int friend_state = marathonDB.getInteger(DBUtilities.FRIEND_STATUS+i, 1);
    			if(friend_state==DBUtilities.FRIEND_STATUS_RUNNER){
					// ランナーの位置情報を取得
					String lati  = marathonDB.getText(DBUtilities.FRIEND_LATITUDE + i, "0.0");
					String longi = marathonDB.getText(DBUtilities.FRIEND_LONGITUDE + i, "0.0");
					// ランナーの走行レーンを取得
					section = marathonDB.getInteger(DBUtilities.FRIEND_SECTION + i, -1);
					//========================================================
					// マップにカーソルを表示する処理
					//========================================================
					double run_lati = Double.parseDouble(lati);
					double run_longi = Double.parseDouble(longi);
					if(run_lati != 0.0 && run_longi != 0.0){

						// 緯度、軽度をひとくくりで設定
						LatLng position = new LatLng(run_lati, run_longi);

						// フレンドリストで割りあてられた使用色を取得
						int my_color = marathonDB.getInteger(DBUtilities.FRIEND_COLOR + i, -1);

						Log.i(CommonUtilities.LOG_TAG, "ID:" + i + " Color:" + my_color + "表示フラグ:" + ol_flg[i] + " 緯度:" + run_lati + " 経度:"+run_longi);

						// カーソルの使用色を初期化
						BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_red);

						// 使用色が割りあてられている場合
						if(my_color != -1){
							// 使用色毎に処理を行う
							switch(my_color){
								// 赤色が設定されている場合
								case CommonUtilities.CURSOR_COLOR_RED:
									// カーソル画像（赤）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_red);
									break;
								case CommonUtilities.CURSOR_COLOR_BLUE:
									// カーソル画像（青）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_blue);
									break;
								case CommonUtilities.CURSOR_COLOR_GREEN:
									// カーソル画像（緑）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_green);
									break;
								case CommonUtilities.CURSOR_COLOR_YELLOW:
									// カーソル画像（黄）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_yellow);
									break;
								case CommonUtilities.CURSOR_COLOR_ORANGE:
									// カーソル画像（橙）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_orange);
									break;
								case CommonUtilities.CURSOR_COLOR_SKY:
									// カーソル画像（水）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_sky);
									break;
								case CommonUtilities.CURSOR_COLOR_GRAY:
									// カーソル画像（灰）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_gray);
									break;
								case CommonUtilities.CURSOR_COLOR_PURPLE:
									// カーソル画像（紫）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_purple);
									break;
								case CommonUtilities.CURSOR_COLOR_YELLOWGREEN:
									// カーソル画像（黄緑）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_yellowgreen);
									break;
								case CommonUtilities.CURSOR_COLOR_PINK:
									// カーソル画像（桃）を設定
									descriptor = BitmapDescriptorFactory.fromResource(R.drawable.runner_icon_pink);
									break;
							}
						}
						GroundOverlayOptions options_ol = new GroundOverlayOptions();
						options_overlay[i] = options_ol;

						// 貼り付ける設定
				    	options_overlay[i].image(descriptor);
				    	//IDBG 0621 アンカー値変更
				    	options_overlay[i].anchor(0.5f,0.5f);
				    	//IDBG 0621 階層順設定
				    	options_overlay[i].zIndex(1);


				    	//===========================================================**
				    	// ズーム処理
				    	//===========================================================**
				    	now_zoom = map.getCameraPosition().zoom;
						Log.i(CommonUtilities.LOG_TAG,"ID:"+ i + " zoom:" + now_zoom);

				    	float zoom_pos = CursorZoom(now_zoom);

				    	options_overlay[i].position(position, zoom_pos);

				    	//===========================================================**
				    	change_no = i;
						// マップに貼り付け・アルファを設定
						if(ol_flg[i] == true){
							Log.i(CommonUtilities.LOG_TAG,"olflg["+ i +"] = " + ol_flg[i]);
							Log.i(CommonUtilities.LOG_TAG,"change_no1:" + change_no);
							overlay[change_no].remove();
							overlay[change_no] = map.addGroundOverlay(options_overlay[change_no]);
							overlay[change_no].setBearing(marathonDB.GetCourseDataAngle(section));
						}
					}
    			}
			}
		}
	}
}
